package com.jy.unkown;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.jy.unkown.view.UnkownADView;
import com.jy.utils.cache.SpManager;
import com.jy.utils.cache.k;
import com.jy.utils.utils.ApkUtils;
import com.jy.utils.utils.MD5;
import com.jy.utils.utils.SpUtil;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class InstallObsever {
    static final String Key = "afasljljstgslwqe123";
    static final String replaceKey = "replace_keyx_asdajo";

    private static final class TT {
        static InstallObsever installObsever = new InstallObsever();
    }


    Map<String, List<InstallCallBack>> installCallBackHashMap = Collections.synchronizedMap(new WeakHashMap<>());
    Map<String, List<String>> installReportUrls = Collections.synchronizedMap(new HashMap<>());
    Map<String, ReplaceBean> stringReplaceBeanMap = Collections.synchronizedMap(new HashMap<>());


    private InstallObsever() {
        initTimers();
    }

    private void initTimers() {
        String json = SpUtil.getString(Key, "");
        if (!TextUtils.isEmpty(json)) {
            try {
                JSONArray jsonArray = new JSONArray(json);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String pack = jsonObject.getString("pack");
                    JSONArray urls = jsonObject.getJSONArray("urls");
                    List<String> stringList = new ArrayList<>();
                    for (int j = 0; j < urls.length(); j++) {
                        String url = urls.getString(j);
                        stringList.add(url);
                    }
                    installReportUrls.put(pack, stringList);
                }
            } catch (Exception exception) {

            }
        }
        Observable.interval(3000, TimeUnit.MILLISECONDS).observeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        checkNotifyInstall();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {

                    }
                });

    }

    private void checkNotifyInstall() {
        Set<String> sets = installReportUrls.keySet();
        if (sets != null) {
            for (String pack : sets) {
                boolean isInstall = ApkUtils.isInstall(pack);
                if (isInstall) {
                    pointPost(installReportUrls.get(pack));
                    List<InstallCallBack> installCallBacks = installCallBackHashMap.get(pack);
                    if (installCallBacks != null) {
                        while (installCallBacks.size() > 0) {
                            installCallBacks.remove(0).installSucc();
                        }
                    }
                    refrefSave(pack, installReportUrls.get(pack), null, true);
                }
            }
        }


    }

    public static InstallObsever getInstance() {
        return TT.installObsever;
    }

    public void register(String pack, List<String> urls, InstallCallBack installCallBack) {
        if (urls == null) {
            return;
        }
        List<InstallCallBack> installCallBacks = installCallBackHashMap.get(pack);
        if (installCallBacks == null) {
            installCallBacks = new ArrayList<>();
        }
        boolean isHave = false;
        for (int i = 0; i < installCallBacks.size(); i++) {
            if (installCallBacks.get(i) == installCallBack) {
                isHave = true;
                break;
            }
        }
        if (!isHave) {
            installCallBacks.add(installCallBack);
            installCallBackHashMap.put(pack, installCallBacks);
            if (installCallBack instanceof UnkownADView) {
                int[] xy = new int[2];
                ((UnkownADView) installCallBack).getLocationInWindow(xy);
                int width = ((UnkownADView) installCallBack).getMeasuredWidth();
                int height = ((UnkownADView) installCallBack).getMeasuredHeight();
                ReplaceBean replaceBean = new ReplaceBean();
                replaceBean.height = height;
                replaceBean.width = width;
                replaceBean.x = xy[0];
                replaceBean.y = xy[1];
                refrefSave(pack, urls, replaceBean, false);
            } else {
                refrefSave(pack, urls, null, false);
            }
            installReportUrls.put(pack, urls);

        }
    }

    private void refrefSave(String newpack, List<String> newurls, ReplaceBean replaceBean, boolean isRemove) {
        String json = SpUtil.getString(Key, "");
        if (!TextUtils.isEmpty(json)) {
            try {
                JSONArray jsonArray = new JSONArray(json);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String pack = jsonObject.getString("pack");
                    JSONArray urls = jsonObject.getJSONArray("urls");

                    List<String> stringList = new ArrayList<>();
                    for (int j = 0; j < urls.length(); j++) {
                        String url = urls.getString(j);
                        stringList.add(url);
                    }
                    installReportUrls.put(pack, stringList);
                }
                List<String> urls = installReportUrls.get(newpack);
                if (urls == null) {
                    urls = new ArrayList<>();
                }
                urls.addAll(newurls);
                installReportUrls.put(newpack, urls);
            } catch (Exception exception) {

            }
        } else {
            installReportUrls.put(newpack, newurls);
        }

        try {
            if (isRemove) {
                installReportUrls.remove(newpack);
                for (int i = 0; i < newurls.size(); i++) {
                    String uurl = newurls.get(i);
                    String md5 = MD5.md5(uurl);
                    SpUtil.remove(replaceKey.concat(md5));
                    stringReplaceBeanMap.remove(uurl);
                }
            } else {
                if (replaceBean != null) {
                    String replaceJSON = new Gson().toJson(replaceBean);
                    for (int i = 0; i < newurls.size(); i++) {
                        String uurl = newurls.get(i);
                        String md5 = MD5.md5(uurl);
                        SpUtil.put(replaceKey.concat(md5), replaceJSON);
                        stringReplaceBeanMap.put(uurl, replaceBean);
                    }
                }
            }
        } catch (Exception exception) {

        }

        try {
            Set<String> keys = installReportUrls.keySet();
            JSONArray jsonArray = new JSONArray();
            for (String pack : keys) {
                List<String> urls = installReportUrls.get(pack);
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("pack", pack);
                    JSONArray urlsJSONArray = new JSONArray();
                    for (int i = 0; i < urls.size(); i++) {
                        String url = urls.get(i);
                        urlsJSONArray.put(url);
                    }
                    jsonObject.put("urls", urlsJSONArray);

                    jsonArray.put(jsonObject);
                } catch (Exception exception) {

                }
            }
            SpUtil.put(Key, jsonArray.toString());
        } catch (Exception exception) {

        }


    }


    public interface InstallCallBack {
        void installSucc();
    }

    protected void pointPost(List<String> winloadUrls) {
        try {
            if (winloadUrls != null) {
                for (int i = 0; i < winloadUrls.size(); i++) {
                    String url = winloadUrls.get(i);
                    String uu = replaceUrl(url);
                    winloadUrls.set(i, uu);
                }
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < winloadUrls.size(); i++) {
                            String url = winloadUrls.get(i);
                            Log.e("InstallObsever", "安装  url=" + url);
                            OkHttpUtil.getInstance().getResult(url);
                        }
                    }
                }).start();


            }

        } catch (Exception exception) {

        }

    }

    private String replaceUrl(String url) throws Exception {
        String jj = SpUtil.getString(replaceKey.concat(MD5.md5(url)), "");
        if (!TextUtils.isEmpty(jj)) {
            ReplaceBean replaceBean = new Gson().fromJson(jj, ReplaceBean.class);

            url = url.replace("__WIDTH__", Integer.toString(replaceBean.width))
                    .replace("__HEIGHT__", Integer.toString(replaceBean.height))
                    .replace("__T_TS__", Long.toString(System.currentTimeMillis() / 1000));
            url = url.replace("__EVENT_TIME_START__", Long.toString(System.currentTimeMillis() - (new Random().nextInt(100) + 10)))
                    .replace("__EVENT_TIME_END__", Long.toString(System.currentTimeMillis()));

        }


        double lat = Double.parseDouble(SpManager.getString(k.lat, "0.0"));
        double lon = Double.parseDouble(SpManager.getString(k.lng, "0.0"));

        if (lat == 100 || lon == 100) {
            lat = lon = 0;
        }
        if (lat != 0) {
            url = url.replace("__LATITUDE__", Double.toString(lat))
                    .replace("__LONGITUDE__", Double.toString(lon));
        }
        return url;
    }
}
